﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Gallio.Framework;
using MbUnit.Framework;
using MbUnit.Framework.ContractVerifiers;
using MobileBroadbandUserBlog.MBLM;
using MobileBroadbandUserBlog.MBLM.Core.Interfaces;
using Rhino.Mocks;
using Rhino.Mocks.Constraints;
using System.IO;
using MobileBroadbandUserBlog.MBLM.Core;

namespace MobileBroadbandLoggingMonitor.FastTests
{
    [TestFixture]
    public class MobileSoftwareLoggerTests
    {
        private readonly MockRepository _mockRepository = new MockRepository();
        private IMobileSoftwareFactory _mobileSoftwareFactory;
        private IMobileSoftware _mobileSoftware;
        private IDirectoryWatcher _directoryWatcher;
        private IChangeStatistics _changeStatistics;

        [SetUp]
        public void SetUp()
        {
            _mobileSoftwareFactory = _mockRepository.StrictMock<IMobileSoftwareFactory>();
            _mobileSoftware = _mockRepository.StrictMock<IMobileSoftware>();
            _directoryWatcher = _mockRepository.StrictMock<IDirectoryWatcher>();
            _changeStatistics = _mockRepository.StrictMock<IChangeStatistics>();
        }

        [Test]
        public void GetSoftwareTest()
        {
            MobileSoftwareLogger mobileSoftwareLogger = new MobileSoftwareLogger(_mobileSoftware, _changeStatistics, _directoryWatcher);
            Assert.AreEqual(_mobileSoftware, mobileSoftwareLogger.GetMobileSoftware());
        }

        [Test]
        public void GetChangeStatisticsTest()
        {
            MobileSoftwareLogger mobileSoftwareLogger = new MobileSoftwareLogger(_mobileSoftware, _changeStatistics, _directoryWatcher);
            Assert.AreEqual(_changeStatistics, mobileSoftwareLogger.GetChangeStatistics());
        }

        [Test]
        [Row(false)]
        [Row(true)]
        public void StartLogging(bool simulateChange)
        {
            GenericConstraint<FileChangeDelegate> fileChangeDelegtateChange =  new GenericConstraint<FileChangeDelegate>();
            using (_mockRepository.Record())
            {
                Expect.Call(() => _changeStatistics.ResetStatistics());
                Expect.Call(_mobileSoftware.GetFolderToMonitor()).Return("Some folder");
                Expect.Call(_mobileSoftware.GetFileFilterToMonitor()).Return("*.*");
                Expect.Call(() => _directoryWatcher.StartWatcher(null, null, null)).IgnoreArguments().Constraints(Is.NotNull(), Is.NotNull(), fileChangeDelegtateChange);
                if (simulateChange)
                {
                    Expect.Call(() => _changeStatistics.AddToStatistics(DateTime.Now)).IgnoreArguments();
                }
            }
            using (_mockRepository.Playback())
            {
                MobileSoftwareLogger mobileSoftwareLogger = new MobileSoftwareLogger(_mobileSoftware, _changeStatistics, _directoryWatcher);
                mobileSoftwareLogger.StartLogging();
                if (simulateChange)
                {
                    bool eventFired = false;
                    mobileSoftwareLogger.LoggingDetected += delegate(string file, WatcherChangeTypes changeType)
                    {
                        eventFired = true;
                    };
                    fileChangeDelegtateChange.GetParameter()("", WatcherChangeTypes.Changed);
                    Assert.IsTrue(eventFired);
                }
            }
        }

        [Test]
        public void StopLogging()
        {
            GenericConstraint<FileChangeDelegate> fileChangeDelegtateChange = new GenericConstraint<FileChangeDelegate>();
            using (_mockRepository.Record())
            {
                Expect.Call(() => _directoryWatcher.StopWatcher());
            }
            using (_mockRepository.Playback())
            {
                MobileSoftwareLogger mobileSoftwareLogger = new MobileSoftwareLogger(_mobileSoftware, _changeStatistics, _directoryWatcher);
                mobileSoftwareLogger.StopLogging();
            }
        }

        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void NullTestConstructorMissingMobileSoftware()
        {
                MobileSoftwareLogger mobileSoftwareLogger = new MobileSoftwareLogger(null, _changeStatistics, _directoryWatcher);
        }


        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void NullTestConstructorMissingMobileChangeStatistics()
        {
                MobileSoftwareLogger mobileSoftwareLogger = new MobileSoftwareLogger(_mobileSoftware, null, _directoryWatcher);
        }

        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void NullTestConstructorMissingMobileDirectoryWatcher()
        {
                MobileSoftwareLogger mobileSoftwareLogger = new MobileSoftwareLogger(_mobileSoftware, _changeStatistics, null);
        }

    }
}
